package com.fw.application.controller.v2.shop.spu;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fw.application.controller.base.BaseController;
import com.fw.common.Builder;
import com.fw.common.IdXD;
import com.fw.constant.Constant;
import com.fw.mes.Result;
import com.fw.system.web.model.dto.UserDto;
import com.fw.system.web.model.entity.*;
import com.fw.system.web.model.form.v2.SpuForm;
import com.fw.system.web.model.form.v2.SpuQuery;
import com.fw.system.web.model.vo.v2.ImagesVo;
import com.fw.system.web.model.vo.v2.SkuVo;
import com.fw.system.web.model.vo.v2.SpuVo;
import com.fw.system.web.service.*;
import com.fw.utils.RandomUtils;
import com.fw.utils.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.fw.enums.ImagesStatusEnum.IMAGES_STATUS_PASS;
import static com.fw.mes.ResultUtils.success;

/**
 * 商户端商品相关API
 */
@RestController
@RequestMapping("/v2/spu")
@Api(tags = "商户端商品相关api")
public class V2SpuController implements BaseController {

    @Autowired
    private IdXD idXD;
    @Autowired
    private IFwSpuService spuService;
    @Autowired
    private IFwAgentRegionService agentRegionService;
    @Autowired
    private IFwShopService shopService;
    @Autowired
    private IFwRuleDatasService ruleDatasService;
    @Autowired
    private IFwImagesService imagesService;
    @Autowired
    private IFwSkuService skuService;
    @Autowired
    private IFwOrderService orderService;

    @Autowired
    private IFwSpucateService spucateService;


    /**
     *  查询商品列表
     */

    @PostMapping("/pageList")
    @ApiOperation("查询我发布的商品列表,详情有 详细内容，列表不展示详细内容")
    public Result<PageInfo<FwSpu>> pageList(@RequestBody @Validated SpuQuery spuQuery){
        UserDto shopDto = getShopDto();
        PageHelper.startPage(spuQuery.getPageNum(),spuQuery.getPageSize());
        List<FwSpu> fwSpus = spuService.list(Wrappers.<FwSpu>lambdaQuery()
                        .eq(spuQuery.getIsOffline()!=-1,FwSpu::getIsOffline,spuQuery.getIsOffline())
                .eq(spuQuery.getIsQuiz() != -1,FwSpu::getIsQuiz,spuQuery.getIsQuiz())
                .eq(spuQuery.getHotSale() != -1,FwSpu::getHotSale,spuQuery.getHotSale())
                .eq(spuQuery.getRecommend() != -1,FwSpu::getIsQuiz,spuQuery.getRecommend())
                .eq(spuQuery.getIsQuiz() != -1,FwSpu::getIsQuiz,spuQuery.getIsQuiz())
                .eq(spuQuery.getStatus() != -1,FwSpu::getStatus,spuQuery.getStatus())

                .like(StringUtils.isNotBlank(spuQuery.getTitle()),FwSpu::getTitle,spuQuery.getTitle())
                .eq(StringUtils.isNotBlank(spuQuery.getCategory()),FwSpu::getCategory,spuQuery.getCategory())
                .eq(FwSpu::getShopId,shopDto.getShopId())
                .orderByDesc(FwSpu::getCreateTime));
        PageInfo pageInfo = new PageInfo(fwSpus);
        return success(pageInfo);
    }

    /**
     * 查询 商品详情
     */
    @GetMapping("/spuInfo/{id}")
    @ApiOperation("查询商品详情")
    public Result<SpuVo> spuInfo(@PathVariable String id){
        FwSpu spu = spuService.getById(id);
        SpuVo spuVo = Builder.of(SpuVo::new).build();
        Assert.isTrue(Objects.nonNull(spu),"暂无找到商品详情");
        BeanUtil.copyProperties(spu,spuVo);
        spuVo.setSkuVoList(skuService.list(Wrappers.<FwSku>lambdaQuery()
                .eq(FwSku::getSpuId, spu.getId())).parallelStream().map(item -> {
            SkuVo skuVo = new SkuVo();
            BeanUtil.copyProperties(item,skuVo);
            return skuVo;
        }).collect(Collectors.toList()));
        spuVo.setImages(imagesService.list(Wrappers.<FwImages>lambdaQuery()
                .eq(FwImages::getBusinessId, spu.getId())).parallelStream().map(item ->{
            ImagesVo imagesVo = new ImagesVo();
            BeanUtil.copyProperties(item,imagesVo);
            return imagesVo;
        }).collect(Collectors.toList()));
        //类目名
     FwSpucate spuCate = spucateService.getById(spu.getCategory());
        spuVo.setCategoryName( spuCate.getCateName() );
        return success(spuVo);
    }


    /**
     * 添加商品
     */
    @PostMapping("/add")
    @ApiOperation("添加商品")
    public Result<Object> add(@Validated @RequestBody SpuForm spu){
        spu.setId(idXD.nextId());
        UserDto shopDto = getShopDto();
        //特卖不判断商户 因为是代理操作的
        if (!Integer.valueOf(1).equals(spu.getIsSale())) {
            spu.setShopId(shopDto.getShopId());
            Assert.isTrue(StringUtils.isNotBlank(spu.getShopId()),"商铺未指定不可添加商品.");
        }

        Result<Object> result = updateAndSave(spu,shopDto.getId());
        if (result != null) { return result; }
        FwSpu fwSpu = Builder.of(FwSpu::new).with(FwSpu::createD, shopDto.getId()).build();
        BeanUtil.copyProperties(spu,fwSpu);
        return success(spuService.save(fwSpu));
    }

    /**
     * 修改商品
     */
    @PostMapping("/update")
    @ApiOperation("修改商品")
    public Result<Object> update(@Validated @RequestBody SpuForm spu){
        UserDto shopDto = getShopDto();
        // 二次校验
        FwSpu spuReal = spuService.getById(spu.getId());
        Assert.isTrue(Objects.nonNull(spuReal) && StringUtils.equals(spuReal.getShopId(),shopDto.getShopId()),"违规操作!");
        Result<Object> result = updateAndSave(spu,shopDto.getId());
        if (result != null) { return result; }

        BeanUtil.copyProperties(spu,spuReal);
        spuReal.updateD(shopDto.getId());
        return success(spuService.updateById(spuReal));
    }

    /**
     * 更新或新增时验证的一些东西，后管有个一摸一样的方法，改的时候要同步修改
     *
     * @param fwSpu
     * @return Result<Object>
     * @author 姚自强
     * @date 2021/8/10
     */
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> updateAndSave(SpuForm fwSpu,String createD) {
        //让利大于0.01，线下除外
        if (fwSpu.getPrice().compareTo(BigDecimal.valueOf(0.01)) < 0 && "0".equals(fwSpu.getIsOffline()))
        { return new Result<>().fail(1,"让利不可低于0.01"); }
        //线下除外
        if (fwSpu.getRealPrice().compareTo(fwSpu.getPrice()) < 0 && "0".equals(fwSpu.getIsOffline()))
        { return new Result<>().fail(1,"当前售价不可低于让利"); }
        BigDecimal divide = fwSpu.getPrice().divide(fwSpu.getRealPrice(), 3, BigDecimal.ROUND_HALF_EVEN);
        if ("0".equals(fwSpu.getIsOffline())) {
            if (fwSpu.getIsQuiz() != null && fwSpu.getIsQuiz() == 1) {
                if ( divide.compareTo(BigDecimal.valueOf(0.35)) < 0) {
                    return new Result<>().fail(1,"成为竞猜商品，让利值需大于售价的35%");
                }
            } else {
                //特卖商品不做判断
                if (Integer.valueOf(0).equals(fwSpu.getIsOffline())) {
                    if (!Integer.valueOf(1).equals(fwSpu.getIsSale()) && divide.compareTo(BigDecimal.valueOf(0.2)) < 0) {
                        return new Result<>().fail(1,"提交商品，让利值需大于售价的20%");
                    }
                }

            }
        }

        //特卖验证
        if (Integer.valueOf(1).equals(fwSpu.getIsSale())) {
            // 获取当前的用户
            FwUser user = getUser();
            if (user == null) {return new Result<>().fail(1,"请重新登录");}
            FwAgentRegion agentRegion = agentRegionService.getOne(Wrappers.<FwAgentRegion>lambdaQuery()
                    .eq(FwAgentRegion::getUserId, user.getId())
                    .eq(FwAgentRegion::getAgent, Constant.IsRuleData.AREA_VIP_MONEY_ID)
                    .eq(FwAgentRegion::getIsDefault, 1));
            if (agentRegion == null) {return new Result<>().fail(1,"仅区县代理可以操作特卖商品");}
            //本代理范围是否已存在特卖商品
            FwSpu saleSpu = spuService.getOne(Wrappers.<FwSpu>lambdaQuery()
                    .eq(FwSpu::getIsSale, 1)
                    .eq(FwSpu::getProvince, agentRegion.getProvince())
                    .eq(FwSpu::getCity, agentRegion.getCity())
                    .eq(FwSpu::getArea, agentRegion.getArea()));
            if (saleSpu != null && ! fwSpu.getId().equals(saleSpu.getId())){
                //说明已存在特卖商品 id不等，不是修改，额外加了一个特卖
                return new Result<>().fail(1,"同地区仅可存在一个特卖商品");
            }

            //填充省市县
            fwSpu.setProvince( agentRegion.getProvince() );
            fwSpu.setCity( agentRegion.getCity() );
            fwSpu.setArea( agentRegion.getArea() );
        }


        //计算消证
        BigDecimal bigDecimal = ruleDatasService.getBigDecimal(Constant.IsRuleData.ONLINE_DISAPPEAR_MAGNIFICATION);
        if (fwSpu.getIsQuiz() != null && fwSpu.getIsQuiz() == 1) {
            fwSpu.setDisappear( fwSpu.getRealPrice() );
        } else {
            fwSpu.setDisappear( fwSpu.getPrice().multiply(bigDecimal) );
        }

        //验证质押商甲
        if (fwSpu.getShopId() != null) {
            if ("1".equals(fwSpu.getIsOffline())) {
                shopService.shopPublishSpu(fwSpu.getShopId(),Constant.ShopRuleData.SHOP_SHANGJIA_OFFLINE);
            }else{
                shopService.shopPublishSpu(fwSpu.getShopId(),Constant.ShopRuleData.SHOP_SHANGJIA_ONLINE);
            }
        }

       // 图片
        spuImagesUp(fwSpu,createD);
        //规格
        spuSkuUp(fwSpu,createD);
        return null;
    }

    private void spuSkuUp(SpuForm fwSpu,String createD) {
        fwSpu.setBalance(Integer.valueOf(0));
        skuService.remove( Wrappers.<FwSku>lambdaQuery().eq(FwSku::getSpuId, fwSpu.getId()) );
        ArrayList<FwSku> fwSkus = Lists.newArrayList();

        fwSpu.getSkuList().forEach(sku->{
            FwSku fwSku = Builder.of(FwSku::new).with(FwSku::setId, idXD.nextId())
                    .with(FwSku::setSpuId, fwSpu.getId())
                    .with(FwSku::createD, createD).build();
                  BeanUtil.copyProperties(sku,fwSku);
            fwSpu.setBalance(fwSpu.getBalance() + sku.getSkuBalance() )  ;
            fwSkus.add(fwSku);
        } );
        skuService.saveBatch( fwSkus );
    }

    private void spuImagesUp(SpuForm fwSpu,String createD) {
        //图片
        imagesService.remove(Wrappers.<FwImages>lambdaQuery().eq(FwImages::getBusinessId, fwSpu.getId()));
        ArrayList<FwImages> imagesLists = Lists.newArrayList();
        fwSpu.getImages().forEach(image -> {
            imagesLists.add(Builder.of(FwImages::new)
                            .with(FwImages::setId,idXD.nextId())
                            .with(FwImages::setBusinessId, fwSpu.getId())
                            .with(FwImages::setStatus,IMAGES_STATUS_PASS.getCode())
                            .with(FwImages::setLinkUrl,image.getLinkUrl())
                            .with(FwImages::createD,createD)
                    .build());
        } );
        imagesService.saveBatch( imagesLists );
    }

    @PostMapping("delete/{spuId}")
    @ApiOperation("删除商品")
    public Result<Object> delete(@PathVariable  String spuId){
        FwSpu spu = spuService.getById(spuId);
        if (spu == null) {
            return new Result<>().fail(1,"未找到该商品->"+spuId);
        }
        // 是否有存根？ 有的话不可删除
        int count = orderService.count(Wrappers.<FwOrder>lambdaQuery().eq(FwOrder::getSpuId, spuId));
        Assert.isTrue(!(count >=1) , "商品不可删除,已有订单关联，只可下架!");
        spuService.removeById(spuId);
        return success("删除成功");
    }

    @GetMapping("/upSpuOrDown/{spuId}/{status}")
    @ApiOperation("上架或者下架商品  0=正常，1=下架")
    public Result upSpuOrDown(@PathVariable String spuId,@PathVariable Integer status){
        FwSpu spu = spuService.getById(spuId);
        if (Objects.isNull(spu)) {
            return new Result<>().fail(1,"未找到该商品->"+spuId);
        }
        spu.setStatus(status);
        spu.updateD(getShopDto().getId());
        spuService.updateById(spu);
        return success();
    }
}
